Android 《第一行代码》简要笔记(一)
第一章,开始启程
Android系统,2003年10月,Andy Rubin创办Android公司。2005年8月,Google收购Android。
系统架构
Android系统基于Linux内核,分为:Linux内核层、系统运行库层、应用框架层、应用层。
版本信息
2008年9月,Android 1.0版本发布。之后2.1、2.2、2.3。
2011年2月,3.0版本,专为平板设计;
2011年10月,Android 4.0版本,统一移动端平台版本。
2014年Google I/O大会,发布Android 5.0,属于较大版本更新。ART替换Dalvik,Material Design以及Android Wear、TV、Auto等。
2015年Google I/O大会,Android 6.0,加入运行时权限。
2016年Google I/O大会,Android 7.0,加入多窗口模式。
2017年Google I/O大会,Android 8.0,通知渠道、画中画、自适应图标等新特性。
Android应用开发特色
四大组件:Activity、Service、Broadcast Receiver、Content Provider。
Intent可用于组件间的信息传递。
开发环境
- JDK
- Android SDK
- Android Studio (也可用Eclipse等其他开发工具,但是官方推荐Android Studio,且确实是最优的选择)
第二章、Activity
onCreate()方法,在api>=21时候,出现了两个
onCreate
方法。123456protected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.second_layout);Log.d(TAG, "onCreate: @Nullable Bundle");}新版的重载的
onCreate
方法1234567891011121314/*** 注意,这个onCreate方法,包含两个参数,在api>=21以上才会调用,用于在手机关机等特殊情况下保存Activity的数据,到outPersistentState中* 若是Android 5.0以下的手机,则仅仅有这个方法的话,会不显示Layout布局,所以必须用上面的那个onCreate方法。* 这两个onCreate也就对应两个onSaveInstanceSate方法。** @param savedInstanceState* @param persistentState*/public void onCreate(@Nullable Bundle savedInstanceState, @Nullable PersistableBundle persistentState) {super.onCreate(savedInstanceState, persistentState);setContentView(R.layout.second_layout);Log.d(TAG, "onCreate: @Nullable PersistableBundle");}Intent包含显式意图和隐式意图,在使用隐式意图启动的时候,注意同时匹配
action
和category
两项。- 1234//拨打电话,记得在AndroidManifest.xml中申请相应权限Intent intent = new Intent(Intent.ACTION_CALL);intent.setData(Uri.parse("tel:10086"));startActivity(intent);
- 123Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse("https://www.google.com"));startActivity(intent);
自定义个Browser响应Action_view的请求
123456//只需要将某个Activity的注册intent-filter修改如下<intent-filter><action android:name="android.intent.action.VIEW"/><category android:name="android.intent.category.DEFAULT"/><data android:scheme="http"/></intent-filter>在startActivity的时候,更严谨的做法是,使用
PackageManager.queryIntentActivity
来查看时候有可以响应inetent的程序,在具体处理。Intent传递数据
intent.putExtra,然后有接收方使用intent.getExtra获取数据。Activity之间的数据传递,
startActivityForResult
和setResult
,然后在onActivityResult
中接收返回的数据。
1、Activity的生命周期
应用程序App中的Activity一般都是处于栈中,属于LIFO
模式,即后进先出。
Activity有四种存在状态:活动、暂停、停止、销毁。
- onCreate(),创建
- onStart(),启动
- onResume(),进入前台模式
- onPause(),退出前台模式,可能是一个Activity被销毁前最后调用到的方法。(这七个方法中)
- onStop(),停止,并非一定会调用到,比如强制销毁程序等非正常操作。
- onDestroy(),销毁
- onRestart(),若在
onDestroy
之前再次返回这个Activity,就会调用本方法。
Activity的生命周期,分为三种模式:
- 完整生命周期,即从
onCreate
到onDestroy
这六个方法包含的全过程。- 可见生命周期,从
onStart
到onStop
之间的生存阶段。- 前台生命周期,在
onResume
到onPause
之间的生存期。
例如:Activity 启动一个Dialog,则其本身只是调用了onPause
,不会执行到onStop
Home键,onPause-->onStop
Back键,onPause-->onStop-->onDestroy
程序避免退出前台而数据丢失,可使用onSaveInstanceState
方法保存数据,在onCreate
中判断非空来取出。Android 5.0之后的版本,这两个方法都多了一个重载。
2、Activity启动模式
standard
、singleTop
、singleTask
、singleInstance
四种启动模式
standard,标准的,每次调用启动,都是新建一个置于栈顶。
singleTop,只有该Activity处于栈顶时,不需要新建,若非栈顶,新建置于栈顶。
singleTask,本app返回栈内无此Activity则新建,若有,不论是否栈顶,都会清理掉activity之上的所有activity,使之处于栈顶。
singleInstance,该Activiy则会独立占用一个新的返回栈,类似与
singleTask
+taskAffinity
。App中,Activity界面,A(standard)—>B (singleInstance)—>C(standard),此时按下返回键,
C—>A,再按返回,APP销毁,显示B程序,再返回便会销毁B程序。
如何知晓当前是哪个Activity在栈顶,使用BaseActivity,其他Activity继承它,使用getClass().getSimpleName()可知当前Activity
随时退出整个App的所有Activity,使用ActivityCollector类。
123456789101112131415161718 > public class ActivityCollector {> public static List<Activity> activities = new ArrayList<>();//Activity集合> //加入集合中> public static void addActivity(Activity activity){> activities.add(activity);> }> //从集合中移除> public static void removeActivity(Activity activity){> activities.remove(activity);> }> //关闭所有> public static void finishAll(){> for(Activity activity : activities){> activity.finish();> }> }> }>
>
然后在
BaseActivity
中添加,移除
12345678910111213141516 > public class BaseActivity extends AppCompatActivity {>> protected void onCreate(Bundle savedInstanceState){> super.onCreate(savedInstanceState);> Log.d("BaseActivity",getClass().getSimpleName());> //将子类的Activity加入到集合中> ActivityCollector.addActivity(this);> }> //子类销毁时候,就从集合中移除>> protected void onDestroy(){> super.onDestroy();> ActivityCollector.removeActivity(this);> }> }>
>
在其他任意地方调用
ActivityCollector.finishAll()
就能结束所有Activity。
让其他Activity调用本Activity的一个写法:
|
|
第三章、UI
1、View
View是Android中所有的控件的基类,包括ViewGroup也是继承自View。
Button
textAllCaps="false"
可以在xml中将Button显示的Text文本禁用全部大写。ProgressBar
style="?android:attr/progressBarStyleHorizontal"
使用?
来引用Android系统的一些属性AlertDialog
dialog.setCancelable(false);
//使在Dialog外部点击,不会消失。另有ProgressDialog
。
2、ViewGroup
继承自View,以前说常用的有五种:AbsoluteLayout
(早已经废弃)、RelativeLayout
、LinearLayout
、TableLayout
(少用)、FrameLayout
新的说法:线性、帧布局、相对布局、百分比布局。
==另:==Android N,伴随AndroidStudio 2.2出现了一个ConstraintLayout
约束布局,据说非常强哦!
线性布局、相对布局、帧布局,需要注意的也就是
Layout_gravity
与gravity
区别,分别是对外和对内。
layout_weight
和weight_sum
权重。表格布局中,注意
TableRow
中最大列数决定整个表格的列数。
PercentLayout
百分比布局,仅仅对线性、相对布局做了扩展,在Android Studio中添加依赖
compile 'com.android.support:percent:24.2.1'
- PercentLinearLayout
- PercentFrameLayout
1234567891011<android.support.percent.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 百分比布局中,可以不用有layout_width和layout_height,--><Buttonandroid:text="Button Text"android:layout_gravity="right|bottom"app:layout_widthPercent="50%"app:layout_heightPercent="50%"</android.support.percent.PercentFrameLayout>\
标签,用于引用共享布局。
ActionBar
其实已经不推荐使用ActionBar,而是更好的TitleBar。都是用
getActionBar
或getSupportActionBar
获取。
自定义View或者ViewGroup可以继承自相应的View或者ViewGroup来复写对应的方法,构造函数,onMesure
、onLayout
和onDraw
等。
ListView
强大的列表控件,配合Adapter
,普通列表常用ArrayAdapter
。现更推荐使用RecyclerView
替代。
同百分比布局类似,RecycleView
也需要单独添加依赖compile 'com.android.support:recyclerview-v7:24.2.1'
使用RecyclerView
需要继承对应的适配器
|
|
在使用RecyclerView
中
|
|
RecyclerView摒弃了ListView的item点击事件,避免事件冲突,所以在RecyclerView中可以对单个的view控件设置点击事件。
.9
图片,用于处理图片在不同屏幕分辨下的正常显示。
第四章、Fragment
Fragment的引入使得Android应用可以更为广泛的适配显示屏幕。Fragment的使用,可以在xml中使用fragment
标签控件,也可以在java代码中动态增删替换。
|
|
使用代码动态操作Fragment
|
|
Fragment与Activity通讯:已知Fragment嵌入在Activity中,两者之间关系紧密却也并非通讯容易。
Activity–>Fragment
123//通过FragmentManager来管理fragment,获取相应的对象,LeftFragment leftFragment = getSupportFragmentManager().findFragmentById(R.id.fg_left);...Fragment–>Activity
123//在Fragment中有个getActivity方法,获得其绑定的Activity对象MainActivity activity = (MainActivity)getActivity();...
同理,Fragment之间的通讯,可以借助它们共有的Activity来作为中介,沟通消息。
1、Fragment生命周期
类似与Activity,Fragment的生命周期同样有运行、暂停、停止和销毁四个状态。
onAttach()
–>onCreateView()
–>onActivityCreated()
–>onDestroyView()
–>onDetach()
为适配不同的移动终端,Android应用需要根据设备显示对应的布局。这里用到了限定符
常用的根据屏幕尺寸、分辨率、方向作为限制符。
尺寸:
small
、normal
、large
、xlarge
分辨率:
ldpi
、mdpi
、hdpi
、xhdpi
、xxhdpi
方向:
land
、port
最小宽度限定符:类似layout_sw600dp
表示这个布局使用于宽度600dp以上的设备显示。
第五章、广播接收者 Broadcast Receiver
Android中广播的消息机制,分为标准广播
和有序广播
。前者面向所有注册接收者,后者根据优先级逐级分发消息,可以在其中中断消息的传播。
广播继承Broadcast Receiver,通过Action过滤接收指定的消息。而LocalBroadcast用于App内部广播,不会被其他App接收到。
广播的注册分为
静态注册
和动态注册
。静态注册就是在
AndroidManifest
中注册receiver
标签。这样可以不启动app就能激活广播。动态注册,实在代码中注册,需要动态注销,避免资源浪费。
注:onReceive()
函数内,不要有耗时操作,避免报错。且其中无法开启线程。
- 接收广播
- 继承
BroadcastReceiver
- 注册广播
- 静态注册,在
AndroidManifest
中注册- 动态注册,在代码中,创建
receiver
对象,并添加intent-filter
过滤action
- registerReceiver();
- 注销广播(动态注册时,才由此步骤,在适当的方法中注销。一般是
onStop(),onDestroy()
)
- 发送广播
使用Intent,添加Action,然后
sendBroadcast(intent)
发送有序广播,
sendOrderedBroadcast(intent,null)
然后receiver根据优先级,逐级接收到消息,可使用
abortBroadcast()
中断向下传输。
本地广播,使用LocalBroadcastManager
获取。
|
|
其注销,也是用LocalBroadcastManager
。在课本示例中有个强制下线功能的演示,通过广播,结合之前的BaseActivity
管理所有Activity的方式,关闭app。其中需要注意的是,注册和注销广播分别在BaseActivity
的onResume
和onPause
中,而非onCreate,onStart
和onStop,onDestroy
中,为的是只让处于前台的Activity响应消息即可,不用每个Activity都去响应。
》》Git 使用命令:
|
|